package me.spring.cloud.components.starter.oauth2.aspect.aspect;

import me.spring.cloud.common.components.oauth2.basic.utils.SecurityUtils;
import me.spring.cloud.common.components.oauth2.inter.UrlAuthProvider;
import me.spring.cloud.common.components.oauth2.userdetails.exception.code.AuthoritiesCode;
import me.spring.cloud.components.starter.oauth2.url.properties.IgnoreUrlProperties;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author: luffy
 * @create: 2018-09-10 10:24
 **/
@Slf4j
@Aspect
public class AuthAspect {

  @Autowired
  private IgnoreUrlProperties ignoreUrlProperties;

  @Autowired(required = false)
  private UrlAuthProvider authProvider;

  private PathMatcher matcher = new AntPathMatcher();

  @Before("@annotation(me.spring.cloud.components.starter.oauth2.aspect.annotation.PreAuth)")
  public void record(JoinPoint joinPoint) throws Throwable {
    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    String reqUrl = request.getRequestURI();
    // 无需权限认证
    if (ignoreUrlProperties.isEnable()) {
      boolean a = ignoreUrlProperties.getUrls().stream().anyMatch(u -> matcher.match(u, reqUrl));
      if (a) {
        return;
      }
    }

    if (null != authProvider) {
      //是否具备权限
      boolean result = authProvider.accessAuth(SecurityUtils.getUsername(), reqUrl);
      if (!result) {
        throw new AccessDeniedException(AuthoritiesCode.NO_AUTHORITY.getDesc());
      }
    }
  }
}
